<template>
  <el-dialog
    title="提示"
    :visible.sync="dialogVisible"
    width="100%"
    height="100%"
    fullscreen="true"
    v-loading="RqOCRing"
    element-loading-text="OCR识别中,请稍后..."
    :before-close="handleClose">

    <el-row :gutter="10" style="height: 100%" class="ocr-dialog-content">
      <el-col :span="4" style="height: 100%">
        <div class="file-list-content">
          <div
            class="file-list"
            v-for="fileItem in fileList"
            :class="{ active: fileItem.active }"
            @click="selectFile(fileItem)"
          >
            <i class="el-icon-files" style="font-size: 40px;"></i>
            <span class="title-type">{{ fileItem.fileName }}</span>
          </div>
        </div>
      </el-col>
      <el-col :span="15" style="height: 100%" ref="centerRef" class="center-col">
        <div style="height: 37px;">
          <el-button
            type="primary"
            v-if="!OCRing"
            @click="OCRIdentify"
            class="mb-10"
          >OCR识别</el-button>
          <el-button
            type="primary"
            v-if="OCRing"
            @click="cancelOCRIdentify"
            class="mb-10"
          >取消OCR识别</el-button>
          <el-button
            type="primary"
            @click="autoObtain"
            class="mb-10"
          >自动获取</el-button>
        </div>
        <div style="height: calc(100% - 37px);" id="ocrContentDiv">
          <FilePreview id="indentificationIframe" ref="indentificationIframeRef">

          </FilePreview>
        </div>
        <div id="toolbar">
          <span><i class="el-icon-close" @click="cancelClip"></i></span>
          <span><i class="el-icon-check" @click="startClip"></i></span>
        </div>
      </el-col>
      <el-col :span="5" style="height: 100%">
          <el-form ref="formFile" :model="formFile" label-width="80px">
            <el-row>
              <el-col :span="24">
                <el-form-item label="文件题名" prop="fileTitle">
                  <el-input v-model.trim="formFile.fileTitle" field-name="fileTitle" placeholder="请输入文件题名" @blur="blueEvent"/>
                </el-form-item>
              </el-col>
              <el-col :span="24">
                <el-form-item label="年度" prop="year">
                  <el-input v-model.trim="formFile.year" field-name="year" placeholder="请输入年度" @blur="blueEvent"/>
                </el-form-item>
              </el-col>
              <el-col :span="24">
                <el-form-item label="文号" prop="wenhao">
                  <el-input v-model.trim="formFile.wenhao" field-name="wenhao" placeholder="请输入文号" @blur="blueEvent"/>
                </el-form-item>
              </el-col>
              <el-col :span="24">
                <el-form-item label="成文时间" prop="sj">
                  <el-input v-model.trim="formFile.sj" field-name="sj" placeholder="请输入成文时间" @blur="blueEvent"/>
                </el-form-item>
              </el-col>
              <el-col :span="24">
                <el-form-item label="责任者" prop="zerenzhe">
                  <el-input v-model.trim="formFile.zerenzhe" field-name="zerenzhe" placeholder="请输入责任者" @blur="blueEvent"/>
                </el-form-item>
              </el-col>
              <el-col :span="24">
                <el-form-item label="备注" prop="beizhu">
                  <el-input v-model.trim="formFile.beizhu" field-name="beizhu" placeholder="请输入备注" @blur="blueEvent"/>
                </el-form-item>
              </el-col>
            </el-row>
          </el-form>
      </el-col>
    </el-row>


<!--    <el-button @click="dialogVisible = false">取 消</el-button>
    <el-button type="primary" @click="dialogVisible = false">确 定</el-button>-->

    <el-dialog
      title="选择字段"
      :visible.sync="fieldVisible"
      width="300px"
      append-to-body
    >
      <el-select
        class="w-100"
        v-model="selectedField"
        placeholder="请选择所需填充的字段"
        clearable
        filterable
      >
        <el-option
          v-for="fieldItem in fieldOptions"
          :key="fieldItem.id"
          :label="fieldItem.showName"
          :value="fieldItem.fieldName"
        >
        </el-option>
      </el-select>

      <span slot="footer">
        <el-button type="primary" @click="setValueByField">确定</el-button>
        <el-button @click="fieldVisible = false">取消</el-button>
      </span>
    </el-dialog>
  </el-dialog>
</template>

<script>
import html2canvas from "html2canvas";
import FilePreview from "@/components/FilePreview/index.vue";
import axios from "axios";
import {fileOcr} from "@/api/system/archFileA";
export default {
  components: {FilePreview},
  data() {
    return {
      fileList:[],
      OCRing: false,
      dialogVisible: false,
      RqOCRing: false,
      currentFileType: "",
      imgSrc: "",
      currentOcrWords: "",
      fieldOptions:[
        {id: "fileTitle", showName:"文件题名", fieldName: "fileTitle"},
        {id: "year", showName:"时间", fieldName: "year"},
        {id: "wenhao", showName:"文号", fieldName: "wenhao"},
        {id: "sj", showName:"成文时间", fieldName: "sj"},
        {id: "zerenzhe", showName:"责任者", fieldName: "zerenzhe"},
        {id: "beizhu", showName:"备注", fieldName: "beizhu"},
      ], // 需要回写的字段
      fieldVisible: false,
      selectedField: "", // 选择的字段

      formFile: { // 文件表单信息  todo 表单字段根据文件类型自动设置
        fileTitle:"",
        year:"",
        wenhao:"",
        sj:"",
        zerenzhe:"",
        beizhu:"",
      },
      lastFieldName: "",
      lastFieldIndex: 0,
      currentFileItem: null,
      canvasClassName:"myCanvas"
    };
  },
  mounted() {

  },
  methods: {
    selectFile(fileItem) {
      this.fileList.forEach((f) => {
        this.$set(f, "active", false);
      });
      fileItem.active = true;
      this.currentFileItem = fileItem;
      this.$refs.indentificationIframeRef.filePreviewPath(fileItem.fileType, fileItem.filePath);
    },
    setFileList(list) {
      this.fileList=list;
      this.$nextTick(() => {
        if(this.fileList.length > 0) {
          // 选中第一条数据
          this.selectFile(this.fileList[0]);
        }
      })
    },
    handleClose(done) {
      done();
      /*this.$confirm('确认关闭？')
        .then(_ => {
          done();
        })
        .catch(_ => {});*/
    },
    showDialog(list) {
      this.dialogVisible = true;
      this.$nextTick(() => {
          this.$refs.indentificationIframeRef.$refs.filePreviewIframeRef.style.display = "block";
          this.setFileList(list);
      })
    },
    OCRIdentify() {
      if (this.OCRing) return;
      this.OCRing = true;
      let offsetLeft = 0, pageNumber = 1;
      let isPDF = false;
      let fileType = this.currentFileItem.fileType;
      // 获取文件类型
      var page;
      if(fileType === "pdf") {
        this.canvasClassName = "myCanvas";
        isPDF = true;
        var contentWindow = this.$refs.indentificationIframeRef.$refs.filePreviewIframeRef.contentWindow;
        page = contentWindow.document.getElementById("viewerContainer");
        pageNumber = contentWindow.document.getElementById("pageNumber")?.value || 1;
        offsetLeft = page.querySelector(".page")?.offsetLeft;

        var textLayerList = contentWindow.document.getElementsByClassName("textLayer");
        for (let item of textLayerList) {
          item.style.display = "none";
        }
      } else if(["jpg","png","jpeg"].indexOf(fileType) !== -1) {
        this.canvasClassName = "imgCanvas";
        page = document.getElementById("imgViewerContainer");
      } else {
        alert("不支持的文件类型");
      }
      html2canvas(page, {
        allowTaint: true,
        useCORS: true,
        width: page.clientWidth,
        height: page.clientHeight,
        x: 0,
        y: page.scrollTop,
        onclone(html) {
          if (!isPDF) return;
          let viewerContainer = html.getElementById("viewerContainer");
          let childNodes = viewerContainer.childNodes[1].childNodes;
          for (let i = 0; i < childNodes.length; i++) {
            const item = childNodes[i];
            let div = document.createElement("div");
            div.classList.add("temp-div");
            div.style.height = "11px";
            viewerContainer.childNodes[1].insertBefore(div, item);
            i++;
            div = null;
          }
        },
      }).then((originCanvas) => {
        originCanvas.className = this.canvasClassName;
        if (isPDF) {
          for (const item of textLayerList) {
            item.style.display = "unset";
          }
          // 隐藏原本的内容展示画布进行截图
          this.$refs.indentificationIframeRef.$refs.filePreviewIframeRef.style.display = "none";
          document.getElementById("ocrContentDiv").style.display = "none";
          if (offsetLeft) originCanvas.style.marginLeft = `${offsetLeft + 10}px`;
        } else {
          this.$refs.indentificationIframeRef.$refs.imgPreviewIframeRef.style.display = "none";
          document.getElementById("ocrContentDiv").style.display = "none";
        }
        this.$refs.centerRef.$el.append(originCanvas);
        let width = originCanvas.offsetWidth;
        let height = originCanvas.offsetHeight;

        // 添加可截图区域
        let clipcanvas = document.createElement("canvas");
        clipcanvas.width = width;
        clipcanvas.height = height;
        clipcanvas.className = this.canvasClassName;
        clipcanvas.style.position = "absolute";
        if (offsetLeft) clipcanvas.style.marginLeft = `${offsetLeft + 10}px`;
        this.$refs.centerRef.$el.append(clipcanvas);

        let ctx = clipcanvas.getContext("2d");
        this.ctx = ctx; // 用于清理画布
        this.originCtx = originCanvas.getContext("2d");
        ctx.fillStyle = "rgba(0,0,0,0.6)";
        ctx.strokeStyle = "green";
        //遮罩层
        ctx.globalCompositeOperation = "source-over";
        ctx.fillRect(0, 0, width, height);

        let start = null;

        clipcanvas.onmousedown = function (e) {
          start = {
            x: e.offsetX,
            y: e.offsetY,
          };
        };
        clipcanvas.onmousemove = function (e) {
          if (start) {
            fill(start.x, start.y, e.offsetX - start.x, e.offsetY - start.y);
          }
        };
        document.addEventListener("mouseup", () => {
          if (start) {
            start = null;
            // 出现工具栏
            let toolbar = document.getElementById("toolbar");
            toolbar.style.top = `${this.clipArea.y + this.clipArea.h + 75}px`;
            toolbar.style.left = `${this.clipArea.x + this.clipArea.w - 95}px`;
            toolbar.style.display = "block";
          }
        });
        const fill = (x, y, w, h) => {
          ctx.clearRect(0, 0, width, height);
          ctx.beginPath();
          //遮罩层
          ctx.globalCompositeOperation = "source-over";
          ctx.fillRect(0, 0, width, height);
          //画框
          ctx.globalCompositeOperation = "destination-out";
          ctx.fillRect(x, y, w, h);
          //描边
          ctx.globalCompositeOperation = "source-over";
          ctx.moveTo(x, y);
          ctx.lineTo(x + w, y);
          ctx.lineTo(x + w, y + h);
          ctx.lineTo(x, y + h);
          ctx.lineTo(x, y);
          ctx.stroke();
          ctx.closePath();
          this.clipArea = {
            x,
            y,
            w,
            h,
          };
        };
      });
    },
    cancelOCRIdentify() {
      this.OCRing = false;
      let fileType = this.currentFileItem.fileType;
      if (fileType.toLowerCase() === "pdf") {
        document.getElementById("ocrContentDiv").style.display = "block";
        this.$refs.indentificationIframeRef.$refs.filePreviewIframeRef.style.display = "unset";
      } else {
        document.getElementById("ocrContentDiv").style.display = "block";
        this.$refs.indentificationIframeRef.$refs.imgPreviewIframeRef.style.display = "block";
      }

      // 移除已产生的canvas
      let centerEl = this.$refs.centerRef.$el;
      const canvasList = document.querySelectorAll("." + this.canvasClassName);
      for (const item of canvasList) {
        centerEl.removeChild(item);
      }
      // 隐藏工具栏
      let toolbar = document.getElementById("toolbar");
      toolbar.style.display = "none";
    },
    // 取消截图
    cancelClip() {
      let width = this.originCtx.canvas.offsetWidth;
      let height = this.originCtx.canvas.offsetHeight;
      this.ctx.clearRect(0, 0, width, height);
      //遮罩层
      this.ctx.globalCompositeOperation = "source-over";
      this.ctx.fillRect(0, 0, width, height);
      // 隐藏工具栏
      let toolbar = document.getElementById("toolbar");
      toolbar.style.display = "none";
    },
    getUnscaledCoordinates(ctx, x, y, w, h) {
      // 获取 canvas 元素
      const canvas = ctx.canvas;

      // 计算缩放比例
      const scaleX = canvas.width / canvas.clientWidth;
      const scaleY = canvas.height / canvas.clientHeight;

      // 计算未经缩放的坐标和尺寸
      const unscaledX = x * scaleX;
      const unscaledY = y * scaleY;
      const unscaledW = w * scaleX;
      const unscaledH = h * scaleY;

      return { x: unscaledX, y: unscaledY, w: unscaledW, h: unscaledH };
    },
    // 开始截图
    startClip() {
      if (this.RqOCRing) return;
      this.RqOCRing = true;

      let {
        x,
        y,
        w,
        h
      } = this.getUnscaledCoordinates(this.originCtx, this.clipArea.x, this.clipArea.y, this.clipArea.w, this.clipArea.h);

      let canvas = document.createElement("canvas");
      canvas.width = w;
      canvas.height = h;
      canvas.className = this.canvasClassName;

      let data = this.originCtx.getImageData(
        x,
        y,
        w,
        h
      );

      let context = canvas.getContext("2d");
      context.putImageData(data, 0, 0);
      let dataURL = canvas.toDataURL("image/png", 1);
      /*this.imgSrc = dataURL;*/
      // 取消截图
      this.cancelOCRIdentify();
      function dataURLtoFile(dataurl, filename) {
        var arr = dataurl.split(","),
          mime = arr[0].match(/:(.*?);/)[1],
          bstr = atob(arr[1]),
          n = bstr.length,
          u8arr = new Uint8Array(n);
        while (n--) {
          u8arr[n] = bstr.charCodeAt(n);
        }
        return new File([u8arr], filename, {type: mime});
      }

      // 开始调用接口 传递参数
      let form = new FormData();
      form.append("file", dataURLtoFile(dataURL, "ocr-png.png")); // 文件file
      /*console.log(form);
      fileOcr(form).then((res) => {
        console.log(res);
      })*/
      this.RqOCRing = true;
      axios.post(process.env.VUE_APP_BASE_API + '/ocr/imageOcrText', form, {
        'Content-type': 'multipart/form-data'
      }).then(res => {
        if(res.status === 200) {
          this.currentOcrWords = res.data.msg;
          // 判断是否为鼠标有聚焦
          if(this.lastFieldName.length !== 0) { // 有聚焦的文本框
            this.setBlueValue();
          } else {
            this.fieldVisible=true;
          }
        }
        // 上传成功后的处理
      }, err => {

      }).finally(res =>{
        this.RqOCRing = false;
      });
    },
    setValueByField() { // 给表单设置值
      this.formFile[this.selectedField]=this.currentOcrWords;
      this.fieldVisible = false;
    },
    setBlueValue() { // 鼠标聚焦赋值
      let text = this.formFile[this.lastFieldName];
      if(text && text.length > 0) {
        this.formFile[this.lastFieldName] = text.slice(0, this.lastFieldIndex) + this.currentOcrWords + text.slice(this.lastFieldIndex);
      } else {
        this.formFile[this.lastFieldName] = this.currentOcrWords;
      }

    },
    blueEvent(e) {
      this.lastFieldName=e.target.getAttribute("field-name");
      this.lastFieldIndex=e.target.selectionStart;
    },
    autoObtain() { // 自动获取
      if(this.currentFileItem) {
        let fileName = this.currentFileItem.fileName;
        let data = {};
        if(fileName.includes("南宁市档案局关于做好2023年档案工作的通知")) {
          data = {
            fileTitle:"南宁市档案局关于做好2023年档案工作的通知",
            year:"2023",
            wenhao:"南档【2023】26号",
            sj:"20230801",
            zerenzhe:"南宁市档案局",
            beizhu:"",
          }
        } else if(fileName.includes("四川省资产评估协会关于修订印发《四川省资产评估机构综合评价暂行办法》的通知")) {
          data = {
            fileTitle:"四川省资产评估协会关于修订印发《四川省资产评估机构综合评价暂行办法》的通知",
            year:"2020",
            wenhao:"川评协〔2020〕4 号",
            sj:"20200121",
            zerenzhe:"四川省资产评估协会",
            beizhu:"",
          }
        }
        this.formFile = data;
      }
    }
  }
};
</script>

<style>
.ocr-dialog-content {
  height: calc(100% - 60px);
}

.el-dialog__body {
  height: calc(100% - 60px);
}

.el-row {
  .center-col {
    flex-grow: 1;
    overflow: hidden;
    position: relative;
  }
}

#toolbar {
  position: absolute;
  padding: 10px;
  display: none;
  background-color: white;
  z-index: 1;

  > span {
    padding: 10px;
    cursor: pointer;

    > i {
      font-size: 20px;
    }
    > .el-icon-close {
      color: red;
    }
    > .el-icon-check {
      color: green;
    }
  }
}

.file-list-content {
  height: calc(100% - 4.8125rem);
  overflow: auto;
  .active {
    box-shadow: inset 0 0 3px 1px green;
  }
}

.file-list {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 5px;
  cursor: pointer;
}

.fu-jian {
  color: #0f3557;
}

.myCanvas {
  margin-top: 32px;
  position: absolute;
}
.imgCanvas {
  position: absolute;
  margin: 0 auto;
  display: flex;
  left: 0;
  right: 0;
}
</style>
